package se.sll.itintegration.catalogue.product.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import lombok.AccessLevel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import se.sll.service.catalogue.common.rest.request.CreateProductRequest;

/**
 *
 * @author khaleddaham
 */
@SuppressWarnings("PMD.UnusedPrivateField")
@Entity
@Data
@Table(name = "product")
@EqualsAndHashCode(of = {"name"})
@NamedQueries({
    @NamedQuery(name = ProductEntity.QUERY_PRODUCTNAME_LIKE, query = "SELECT p FROM ProductEntity p WHERE p.name LIKE :name"),
    @NamedQuery(name = ProductEntity.QUERY_FIND_BY_CODE, query = "SELECT p FROM ProductEntity p JOIN p.codes c WHERE c.code = :code"),
    @NamedQuery(name = ProductEntity.QUERY_FIND_BY_OID_AND_CODE, query = "SELECT p FROM ProductEntity p JOIN p.codes c WHERE c.code = :code AND c.codeSystem.oid = :oid")
})
public class ProductEntity implements Serializable {

    public static final String QUERY_PRODUCTNAME_LIKE = "ProductEntity.QUERY_PRODUCTNAME_LIKE";
    public static final String QUERY_FIND_BY_CODE = "ProductEntity.QUERY_FIND_BY_CODE";
    public static final String QUERY_FIND_BY_OID_AND_CODE = "ProductEntity.QUERY_FIND_BY_OID_AND_CODE";
    public static final ArrayList<String> counties = new ArrayList<>(
        Arrays.asList("01", "03", "04", "05", "06", "07", "08", "09", "10", "12", 
                "13", "14", "17", "18", "19", "20", "21", "22", "23", "24", "25"));
    
    @Id
    @GeneratedValue
    @Getter(AccessLevel.NONE)
    @Setter(AccessLevel.NONE)
    private Long id;
    @NotNull
    @Enumerated(EnumType.STRING)
    private CreateProductRequest.STATUS status;
    @NotNull
    @Column(unique = true, updatable = false)
    private String name; // @TODO byt till productCode
    private String displayName; // @TODO byt till name
    @Column(length = 1024)
    private String description;
    @NotNull
    @Temporal(TemporalType.TIMESTAMP)
    private Date creationTime;
    @Temporal(TemporalType.TIMESTAMP)
    private Date updateTime;
    private String updatedByHsaid;
    @Fetch(FetchMode.SUBSELECT)

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinTable(name = "product_code", joinColumns = {
        @JoinColumn(name = "product_id", nullable = false, updatable = false)},
            inverseJoinColumns = {
                @JoinColumn(name = "code_id",
                        nullable = false, updatable = false)})
    private Set<CodeEntity> codes;
    private String parentProductId;
    private String county;
    //private Set<CodeEntity> resources;
}